import os
import webbrowser
from tkinter import filedialog, messagebox

import ttkbootstrap as ttk
from PyPDF2 import PdfReader, PdfWriter
from ttkbootstrap.constants import *


class PDFSplitPage(ttk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.pdf_path = None
        self.total_pages = 0
        self.setup_ui()

    def setup_ui(self):
        # 创建上传按钮
        upload_frame = ttk.Frame(self)
        upload_frame.pack(fill=X, pady=10)

        self.upload_btn = ttk.Button(
            upload_frame,
            text="上传PDF",
            command=self.upload_pdf,
            style="primary.TButton"
        )
        self.upload_btn.pack(side=LEFT, padx=5)

        # 显示文件路径和页数
        self.path_label = ttk.Label(upload_frame, text="未选择PDF文件")
        self.path_label.pack(side=LEFT, padx=5)

        self.pages_label = ttk.Label(upload_frame, text="")
        self.pages_label.pack(side=LEFT, padx=5)

        # 预览按钮
        self.preview_btn = ttk.Button(
            upload_frame,
            text="预览",
            command=self.preview_pdf,
            style="info.TButton",
            state=DISABLED
        )
        self.preview_btn.pack(side=LEFT, padx=5)

        # 创建拆分选项框架
        options_frame = ttk.LabelFrame(self, text="拆分选项")
        options_frame.pack(fill=X, padx=10, pady=10)

        # 每页拆分选项
        self.split_by_page = ttk.BooleanVar(value=True)
        ttk.Radiobutton(
            options_frame,
            text="按页拆分",
            variable=self.split_by_page,
            value=True
        ).pack(anchor=W, padx=5, pady=5)

        # 自定义范围拆分选项
        ttk.Radiobutton(
            options_frame,
            text="自定义范围",
            variable=self.split_by_page,
            value=False
        ).pack(anchor=W, padx=5, pady=5)

        # 范围输入框
        range_frame = ttk.Frame(options_frame)
        range_frame.pack(fill=X, padx=5, pady=5)

        ttk.Label(range_frame, text="页码范围:").pack(side=LEFT)
        self.range_entry = ttk.Entry(range_frame, width=20)
        self.range_entry.pack(side=LEFT, padx=5)
        ttk.Label(range_frame, text="(例如: 1-3,5,7-9)").pack(side=LEFT)

        # 拆分按钮
        self.split_btn = ttk.Button(
            self,
            text="开始拆分",
            command=self.split_pdf,
            style="success.TButton",
            state=DISABLED
        )
        self.split_btn.pack(pady=10)

        # 进度条
        self.progress = ttk.Progressbar(
            self,
            mode='determinate',
            length=300
        )
        self.progress.pack(pady=10)

        # 导出文件信息
        self.export_frame = ttk.LabelFrame(self, text="导出文件")
        self.export_frame.pack(fill=X, padx=10, pady=10)

        self.export_path_label = ttk.Label(self.export_frame, text="未导出文件")
        self.export_path_label.pack(side=LEFT, padx=5)

        self.preview_export_btn = ttk.Button(
            self.export_frame,
            text="预览",
            command=self.preview_export,
            style="info.TButton",
            state=DISABLED
        )
        self.preview_export_btn.pack(side=LEFT, padx=5)

    def upload_pdf(self):
        file_path = filedialog.askopenfilename(
            filetypes=[("PDF文件", "*.pdf")]
        )
        if file_path:
            self.pdf_path = file_path
            self.path_label.config(text=file_path)

            # 获取PDF页数
            try:
                reader = PdfReader(file_path)
                self.total_pages = len(reader.pages)
                self.pages_label.config(text=f"共 {self.total_pages} 页")
                self.preview_btn.config(state=NORMAL)
                self.split_btn.config(state=NORMAL)
            except Exception as e:
                messagebox.showerror("错误", f"读取PDF失败：{str(e)}")

    def preview_pdf(self):
        try:
            webbrowser.open(self.pdf_path)
        except Exception as e:
            messagebox.showerror("错误", f"预览失败：{str(e)}")

    def parse_page_range(self, range_str, total_pages):
        pages = set()
        try:
            for part in range_str.split(','):
                if '-' in part:
                    start, end = map(int, part.split('-'))
                    if 1 <= start <= end <= total_pages:
                        pages.update(range(start, end + 1))
                else:
                    page = int(part)
                    if 1 <= page <= total_pages:
                        pages.add(page)
            return sorted(pages)
        except:
            return None

    def split_pdf(self):
        if not self.pdf_path:
            messagebox.showerror("错误", "请先上传PDF文件")
            return

        output_dir = filedialog.askdirectory()
        if not output_dir:
            return

        try:
            self.progress['value'] = 0
            self.update_idletasks()

            reader = PdfReader(self.pdf_path)
            total_pages = len(reader.pages)
            base_name = os.path.splitext(os.path.basename(self.pdf_path))[0]

            if self.split_by_page.get():
                # 按页拆分
                for i in range(total_pages):
                    writer = PdfWriter()
                    writer.add_page(reader.pages[i])

                    output_path = os.path.join(
                        output_dir,
                        f"{base_name}_page_{i + 1}.pdf"
                    )

                    # 检查文件是否存在
                    if os.path.exists(output_path):
                        if not messagebox.askyesno("确认", f"文件 {os.path.basename(output_path)} 已存在，是否覆盖？"):
                            continue

                    # 设置PDF标题
                    title = os.path.splitext(os.path.basename(output_path))[0]
                    writer.add_metadata({'/Title': title})

                    with open(output_path, 'wb') as output_file:
                        writer.write(output_file)

                    progress = (i + 1) / total_pages * 100
                    self.progress['value'] = progress
                    self.update_idletasks()
            else:
                # 自定义范围拆分
                page_range = self.parse_page_range(
                    self.range_entry.get(),
                    total_pages
                )

                if not page_range:
                    messagebox.showerror("错误", "无效的页码范围")
                    return

                writer = PdfWriter()
                for i, page_num in enumerate(page_range):
                    writer.add_page(reader.pages[page_num - 1])

                    progress = (i + 1) / len(page_range) * 100
                    self.progress['value'] = progress
                    self.update_idletasks()

                output_path = os.path.join(
                    output_dir,
                    f"{base_name}_split.pdf"
                )

                # 检查文件是否存在
                if os.path.exists(output_path):
                    if not messagebox.askyesno("确认", f"文件 {os.path.basename(output_path)} 已存在，是否覆盖？"):
                        return

                # 设置PDF标题
                title = os.path.splitext(os.path.basename(output_path))[0]
                writer.add_metadata({'/Title': title})

                with open(output_path, 'wb') as output_file:
                    writer.write(output_file)

            self.progress['value'] = 100
            self.update_idletasks()

            # 更新导出文件信息
            self.export_path_label.config(text=output_dir)
            self.preview_export_btn.config(state=NORMAL)

            messagebox.showinfo("成功", "PDF文件已拆分并保存")

        except Exception as e:
            messagebox.showerror("错误", f"拆分失败：{str(e)}")
        finally:
            self.progress['value'] = 0

    def preview_export(self):
        try:
            webbrowser.open(self.export_path_label.cget("text"))
        except Exception as e:
            messagebox.showerror("错误", f"预览失败：{str(e)}")
